package com.winhxd.b2c.order.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.winhxd.b2c.common.cache.Cache;
import com.winhxd.b2c.common.cache.Lock;
import com.winhxd.b2c.common.cache.RedisLock;
import com.winhxd.b2c.common.constant.BusinessCode;
import com.winhxd.b2c.common.constant.CacheName;
import com.winhxd.b2c.common.domain.PagedList;
import com.winhxd.b2c.common.domain.ResponseResult;
import com.winhxd.b2c.common.domain.order.condition.ShopCartEditCondition;
import com.winhxd.b2c.common.domain.order.condition.ShopCartQueryCondition;
import com.winhxd.b2c.common.domain.order.condition.ShopCartRemoveCondition;
import com.winhxd.b2c.common.domain.order.enums.OrderCartStatusEnum;
import com.winhxd.b2c.common.domain.order.model.OrderShoppingCart;
import com.winhxd.b2c.common.domain.order.vo.ShopCartVO;
import com.winhxd.b2c.common.domain.product.condition.ProductSkuListCondition;
import com.winhxd.b2c.common.domain.product.vo.ProductShopcarSkuVO;
import com.winhxd.b2c.common.exception.BusinessException;
import com.winhxd.b2c.common.feign.product.ProductServiceClient;
import com.winhxd.b2c.order.dao.OrderShoppingCartMapper;
import com.winhxd.b2c.order.service.OrderShopCartService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 购物车实现类
 * @author suhaochan
 * @date 2019/1/8 14:03:15
 */
@Service
public class OrderShopCartServiceImpl implements OrderShopCartService {
	
	private static final Logger logger = LoggerFactory.getLogger(OrderShopCartServiceImpl.class);

	//购物车产品种类上限为99
	private static final int SHOPCART_PRODUCTTYPENUM_MAX = 99;

	//购物车单个产品最大购买数量
	private static final int SHOPCART_MAX_NUM = 99;
	
	@Autowired
	private OrderShoppingCartMapper orderShoppingCartMapper;
	
	@Autowired
	private ProductServiceClient productServiceClient;
	
	@Autowired
    private Cache cache;
	
	@Override
	public PagedList<ShopCartVO> findShopCart(ShopCartQueryCondition condition) {
		PagedList<ShopCartVO> result = new PagedList<ShopCartVO>();
		result.setPageNo(condition.getPageNo());
		result.setPageSize(condition.getPageSize());
		Page page = PageHelper.startPage(condition.getPageNo(), condition.getPageSize());
		//根据用户ID获取有效的购物车列表数据
		OrderShoppingCart queryModel = new OrderShoppingCart();
		queryModel.setCustomerId(condition.getCustomerId());
		queryModel.setStatus(OrderCartStatusEnum.EFFECTIVE.getStatusCode());
		List<OrderShoppingCart> shopCarts = orderShoppingCartMapper.selectByModel(queryModel);
		if (CollectionUtils.isEmpty(shopCarts)) {
			result.setTotalRows(0);
			result.setData(null);
			return result;
		}
		//从购物车中获取skuId集合
		List<Long> skuIds = getSkuIdListByShopCart(shopCarts);
		//根据skuID集合获取购物车商品信息
		Map<Long, ProductShopcarSkuVO> shopCartProds = getShopCartProdBySkuIds(condition.getCustomerId(),skuIds);
		//总商品信息统计
		List<ShopCartVO> shopCartVOList = new ArrayList<ShopCartVO>();
		//无库存商品信息统计
		List<ShopCartVO> noStockShopCartVOList = new ArrayList<ShopCartVO>();
		//下架商品信息统计
		List<ShopCartVO> unSaleShopCartVOList = new ArrayList<ShopCartVO>();
		//根据商品服务返回的商品信息组合购物车信息
		for (OrderShoppingCart orderShoppingCart : shopCarts) {
			ProductShopcarSkuVO productShopcarSkuVO = shopCartProds.get(orderShoppingCart.getSkuId());
			ShopCartVO shopCartVO = new ShopCartVO();
			if (productShopcarSkuVO != null) {
				BeanUtils.copyProperties(productShopcarSkuVO,shopCartVO);
				shopCartVO.setShopCarId(orderShoppingCart.getId());
				shopCartVO.setNum(orderShoppingCart.getNum());
				//售卖价格为空时，默认为0
				if (productShopcarSkuVO.getSalePrice() == null) {
					shopCartVO.setSalePrice(BigDecimal.ZERO);
				}
				if (productShopcarSkuVO.getSaleStatus() == 0) {
					//已下架
					unSaleShopCartVOList.add(shopCartVO);
				} else if (productShopcarSkuVO.getStockStatus() == 0) {
					//无库存
					noStockShopCartVOList.add(shopCartVO);
				} else {
					shopCartVOList.add(shopCartVO);
				}
			}
			
		}
		//无库存/已下架的商品排在最后
		shopCartVOList.addAll(unSaleShopCartVOList);
		shopCartVOList.addAll(noStockShopCartVOList);
		
		result.setData(shopCartVOList);
		result.setTotalRows(page.getTotal());
		return result;
	}
	
	@Transactional
	@Override
	public int saveShopCart(ShopCartEditCondition condition) {
		//禁止用户频繁添加购物车
		String lockKey = CacheName.CACHE_KEY_CUSTOMER_SHOPCART_REPEAT + condition.getCustomerId();
        Lock lock = new RedisLock(cache, lockKey, 1000);
        try {
            if (lock.tryLock()) {
            	//校验
                validateBeforeSaveShopCart(condition);
                
                OrderShoppingCart queryModel = new OrderShoppingCart();
        		queryModel.setCustomerId(condition.getCustomerId());
        		queryModel.setSkuId(condition.getSkuId());
        		queryModel.setStatus(OrderCartStatusEnum.EFFECTIVE.getStatusCode());
        		List<OrderShoppingCart> shopCarts = orderShoppingCartMapper.selectByModel(queryModel);
        		Date current = new Date();
        		if (!CollectionUtils.isEmpty(shopCarts)) {
        			//更新--如果该产品已经在购物车中，则增加购买数量
        			OrderShoppingCart shopCartsUpdate =  shopCarts.get(0);
        			//校验购买数量
					if (shopCartsUpdate.getNum()+condition.getNum() > SHOPCART_MAX_NUM){
						throw new BusinessException(BusinessCode.CODE_403008);
					}
        			shopCartsUpdate.setNum(shopCartsUpdate.getNum()+condition.getNum());
        			shopCartsUpdate.setUpdated(current);
        			shopCartsUpdate.setUpdatedBy(condition.getCustomerId().toString());
        			return orderShoppingCartMapper.updateByPrimaryKey(shopCartsUpdate);
        		} else {
        			//新增
        			OrderShoppingCart shopCartsInsert = new OrderShoppingCart();
                    shopCartsInsert.setCustomerId(condition.getCustomerId());
                    shopCartsInsert.setSpuId(condition.getSpuId());
                    shopCartsInsert.setSkuId(condition.getSkuId());
                    shopCartsInsert.setNum(condition.getNum());
                    shopCartsInsert.setStatus(OrderCartStatusEnum.EFFECTIVE.getStatusCode());
                    shopCartsInsert.setCreated(current);
                    shopCartsInsert.setCreatedBy(condition.getCustomerId().toString());
                    shopCartsInsert.setUpdated(current);
                    shopCartsInsert.setUpdatedBy(condition.getCustomerId().toString());
                    return orderShoppingCartMapper.insertSelective(shopCartsInsert);
        		}
        		
            }else {
                throw new BusinessException(BusinessCode.CODE_403005);
            }
        } finally {
            lock.unlock();
        }
		
	}
	
	@Transactional
	@Override
	public int modifyShopCart(ShopCartEditCondition condition) {
		OrderShoppingCart oldShopCart = orderShoppingCartMapper.selectByPrimaryKey(condition.getShopCarId());
		if (oldShopCart == null || oldShopCart.getStatus() == 0) {
			throw new BusinessException(BusinessCode.CODE_403007);
		}
		oldShopCart.setNum(condition.getNum());
		oldShopCart.setUpdatedBy(condition.getCustomerId().toString());
		oldShopCart.setUpdated(new Date());
		return orderShoppingCartMapper.updateByPrimaryKey(oldShopCart);
	}
	
	@Transactional
	@Override
	public int removeShopCart(ShopCartRemoveCondition condition) {
		if (CollectionUtils.isEmpty(condition.getShopCarIds())) {
			//购物车ID为空，则根据用户ID清空购物车
			return orderShoppingCartMapper.deleteByCustomerId(condition.getCustomerId());
		} else {
			//购物车ID不为空，则根据购物车ID批量删除购物车
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("updatedBy", condition.getCustomerId());
			params.put("ids", condition.getShopCarIds());
			return orderShoppingCartMapper.deleteByIds(params);
		}
	}

	@Override
	public int getShopCartProductTypeNum(ShopCartQueryCondition condition) {
		return orderShoppingCartMapper.selectProductTypeNumByCustomerId(condition.getCustomerId());
	}


	/**
	 * 
	 * @author suhaochan
	 * @date 2019年1月8日 下午6:12:38 
	 * @Description 添加购物车前的校验
	 * @param 
	 * @return
	 */
	private void validateBeforeSaveShopCart(ShopCartEditCondition condition) {
		//购物车商品种类上限为99
		int count = orderShoppingCartMapper.selectProductTypeNumByCustomerId(condition.getCustomerId());
		if (count >= SHOPCART_PRODUCTTYPENUM_MAX) {
			throw new BusinessException(BusinessCode.CODE_403004);
		}
	}

	/**
	 *
	 * @author suhaochan
	 * @date 2019年1月8日 下午4:20:07 
	 * @Description 根据skuID集合获取购物车商品信息
	 * @param customerId 用户ID，skuIds 商品skuId集合
	 * @return
	 */
	private Map<Long, ProductShopcarSkuVO> getShopCartProdBySkuIds(Long customerId,List<Long> skuIds) {
		ProductSkuListCondition condition =  new ProductSkuListCondition();
		condition.setCustomerId(customerId);
		condition.setSkuIdList(skuIds);
		ResponseResult<Map<Long, ProductShopcarSkuVO>> result = productServiceClient.findShopcarSkuList(condition);
		if (result == null || result.getCode() != BusinessCode.CODE_OK || CollectionUtils.isEmpty(result.getData())) {
			logger.info("OrderShopCartServiceImpl{} ->getShopCartProdBySkuIds 商品服务调用获取购物车商品sku列表接口失败");
			throw new BusinessException(BusinessCode.CODE_403002);
		}
		return result.getData();
	}

	/**
	 * 
	 * @author suhaochan
	 * @date 2019年1月8日 下午2:50:31 
	 * @Description 从购物车实体集合中获取skuId集合
	 * @param 
	 * @return
	 */
	private List<Long> getSkuIdListByShopCart(List<OrderShoppingCart> shopCarts) {
		List<Long> skuIds = new ArrayList<Long>();
        if (!CollectionUtils.isEmpty(shopCarts)) {
        	skuIds = shopCarts.stream()
                    .map(shopCart -> shopCart.getSkuId()).collect(Collectors.toList());
        }
        return skuIds;
	}

}
